package com.wwm.elasticsearch.unit;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.google.gson.JsonObject;
import com.wwm.elasticsearch.entity.MyArticle;
import io.searchbox.core.*;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import io.searchbox.core.SearchResult.Hit;

import org.elasticsearch.search.builder.SearchSourceBuilder;
import com.google.gson.GsonBuilder;

import io.searchbox.client.JestClient;
import io.searchbox.client.JestClientFactory;
import io.searchbox.client.JestResult;
import io.searchbox.client.config.HttpClientConfig;
import io.searchbox.cluster.Health;
import io.searchbox.cluster.NodesInfo;
import io.searchbox.cluster.NodesStats;
import io.searchbox.indices.ClearCache;
import io.searchbox.indices.CloseIndex;
import io.searchbox.indices.CreateIndex;
import io.searchbox.indices.DeleteIndex;
import io.searchbox.indices.Flush;
import io.searchbox.indices.IndicesExists;
import io.searchbox.indices.Optimize;
import io.searchbox.indices.mapping.PutMapping;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * ElasticSearch JestClient 单元测试示例
 * @author wwm
 * @date 2018-05-11 11:08:12
 * @email wanming0522@163.com
 */
public class JestClientUnit
{
    /** ES索引-有点类似于数据库 */
    private static String indexName = "index-es-unit";

    /** ES类型-有点类似于表 */
    private static String typeName = "article";

    /** ES服务器地址 */
    private static String serverUri = "http://localhost:9200";

    private static JestClient jestClient;

    @Before
    public void getClient() throws Exception
    {
		JestClientFactory factory = new JestClientFactory();  
        factory.setHttpClientConfig(new HttpClientConfig  
               .Builder(serverUri)
               .gson(new GsonBuilder().setDateFormat("yyyy-MM-dd'T'hh:mm:ss").create())
               .connTimeout(1500)
               .readTimeout(3000)
               .multiThreaded(true)
               .build());
        jestClient=factory.getObject();
    }
  
    @After
    public void tearDown() throws Exception
    {
        closeJestClient(jestClient);  
    }  

    /**  
     * 关闭JestClient客户端  
     * @param jestClient  
     * @throws Exception  
     */  
    public void closeJestClient(JestClient jestClient) throws Exception
    {
        if (jestClient != null)
        {
           jestClient.shutdownClient();
        }  
    }

    /**
     * ---------------------------开始测试--------------------------
     */
    
    /**
     * 创建索引
     * @throws Exception
     */
    @Test
    public void createIndex() throws Exception
    {
        JestResult jr = jestClient.execute(new CreateIndex.Builder(indexName).build());
    	System.out.println("ES索引创建完成："+jr.isSucceeded());
    }  
  
    /**
     * Put映射 
     * @throws Exception
     */
    @Test  
    public void createIndexMapping() throws Exception
    {
        String source = "{\"" + typeName + "\":{\"properties\":{"
                + "\"author\":{\"type\":\"string\"}"
                + ",\"title\":{\"type\":\"string\"}"
                + ",\"content\":{\"type\":\"string\"}"
                + ",\"date\":{\"type\":\"date\",\"format\":\"yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis\"}"
                + "}}}";

        System.out.println(source);  
        
        PutMapping putMapping = new PutMapping.Builder(indexName, typeName, source).build();  
        JestResult jr = jestClient.execute(putMapping);

        System.out.println("ES类型创建完成:"+jr.isSucceeded());
    }
    
    /**
     * 单条添加
     * @throws IOException 
     */
    @Test
    public void insertMultiple() throws IOException
    {
       	MyArticle myArticle=new MyArticle();
        myArticle.setAuthor("ABC");
        myArticle.setTitle("厉害了我的国2");
        myArticle.setContent("大型纪录电影《厉害了，我的国》自3月2日上映以来，票房已过1.1亿元，更刷新了纪录片首日票房，让观众们心潮澎湃。作为一部以展示国家辉煌建设成就的“硬纪实”电影，影片将宏大场面和温情视角相结合，通过关注人的故事，讲述“大国”“小家”紧密相依的道理，为宏大叙事类纪录片的突破做出了有益尝试。");
        myArticle.setDate(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date()));

    	Index index = new Index.Builder(myArticle).index(indexName).type(typeName).build();

		JestResult jestResult1 = jestClient.execute(index);
		System.out.println("ES单条添加："+jestResult1.getJsonString());
    }
    
    /**
     * 批量添加
     * Bulk
     * @throws IOException 
     */
    @Test
    public void bulkIndex() throws IOException
    {
        MyArticle myArticle1=new MyArticle();
        myArticle1.setAuthor("李四");
        myArticle1.setTitle("空姐深夜打车遇害 滴滴悬赏100万元寻找疑凶司机");
        myArticle1.setContent("今天，“空姐深夜打顺风车遇害 ”一事引发关注。对此，滴滴平台告诉北青报记者，因涉及重要事项，滴滴公司向全社会公开征集线索，寻找一位嫌疑司机（名为刘振华的顺风车司机）对提供线索的热心人，滴滴将视线索重要程度给予最高100万人民币的奖励。");
        myArticle1.setDate(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date()));

        MyArticle myArticle2=new MyArticle();
        myArticle2.setAuthor("王二");
        myArticle2.setTitle("以色列28架战机一夜之间对叙利亚发射60枚火箭弹");
        myArticle2.setContent("据今日俄罗斯报道，俄罗斯国防部表示，28架以色列战机一夜之间在叙利亚发射了约60枚火箭弹，大部分被叙利亚防空系统拦截。以色列军方当地时间周四（10日）表示，以军已对叙利亚境内“几乎所有”伊朗设施站进行了空袭，作为伊朗对戈兰高地发射20枚火箭弹的回击。");
        myArticle2.setDate(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date()));

        MyArticle myArticle3=new MyArticle();
        myArticle3.setAuthor("麻子");
        myArticle3.setTitle("多人在京东超市买到假茅台 京东:运输中被调包");
        myArticle3.setContent("近日，一则山东多位客户在京东平台购买到假冒茅台酒的消息在互联网上引发关注，5月11日晚，京东酒品业务部通过“京东超市”官方微博对此回应称，由京东山东某库房发出的“43度飞天茅台500ml”在运输过程中出现了被调包的现象，京东将与供货商北京糖业烟酒集团京酒销售有限公司联合报警。   ");
        myArticle3.setDate(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date()));

        MyArticle myArticle4=new MyArticle();
        myArticle4.setAuthor("东邪");
        myArticle4.setTitle("看哭了！叙利亚儿童含泪追问：我们做错了什么？");
        myArticle4.setContent("叙利亚危机以来，7年战争给叙利亚儿童带来难以承受的心理创伤，他们饱受战乱摧残，还要忍受饥饿、承受丧亲之痛。听听他们对战争的控诉！愿世界再无战争。");
        myArticle4.setDate(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date()));

        MyArticle myArticle5=new MyArticle();
        myArticle5.setAuthor("西毒");
        myArticle5.setTitle("鸿茅药酒风波续:鸿茅药酒从国家品牌计划官网消失");
        myArticle5.setContent("身陷风波的鸿茅药酒连日来备受质疑。人们发现这家企业曾在2017年、2018年两度入选国家品牌计划企业，此前一声明中它亦强调“入选计划是对我们的认可”。21日有记者查看国家品牌计划官网，发现鸿茅药酒已消失在首页“行业领跑者”名单中。");
        myArticle5.setDate(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date()));


        Bulk bulk = new Bulk.Builder().defaultIndex(indexName).defaultType(typeName)
				.addAction(Arrays.asList(
						new Index.Builder(myArticle1).build(),
						new Index.Builder(myArticle2).build(),
						new Index.Builder(myArticle3).build(),
                        new Index.Builder(myArticle4).build(),
						new Index.Builder(myArticle5).build()
				)).build();

    	JestResult jestResult=jestClient.execute(bulk);

    	System.out.println("ES批量添加："+jestResult.getJsonString());
    }

	
    /**
     * 单值完全匹配查询
     * @throws Exception
     */
    @Test  
    public void termQuery() throws Exception
    {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        QueryBuilder queryBuilder = QueryBuilders.termQuery("author.keyword", "李四");
        searchSourceBuilder.query(queryBuilder);
        String query = searchSourceBuilder.toString();
        System.out.println("[精确匹配]查询条件："+query);

        Search search = new Search.Builder(query).addIndex(indexName).addType(typeName).build();
        SearchResult result = jestClient.execute(search);
        
        List<Hit<Object, Void>> hits = result.getHits(Object.class);  
        System.out.println("[精确匹配]查询Size:" + hits.size());

        for (Hit<Object, Void> hit : hits)
        {
          Object news = hit.source;  
          System.out.println("[精确匹配]查询结果:" +news.toString());
        }  
    }  
    
    
    /**
     * 多值完全匹配查询  
     * @throws Exception
     */
    @Test  
    public void termsQuery() throws Exception
    {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        QueryBuilder queryBuilder = QueryBuilders.termsQuery("author.keyword", new String[]{ "东邪", "西毒" });
        searchSourceBuilder.query(queryBuilder);  
        searchSourceBuilder.size(10);  
        searchSourceBuilder.from(0);  
        String query = searchSourceBuilder.toString();

        System.out.println("[多条精确匹配]查询条件："+query);
        
        Search search = new Search.Builder(query)  
                .addIndex(indexName)  
                .addType(typeName)
                .build();  
        SearchResult result = jestClient.execute(search); 
        
        List<Hit<Object, Void>> hits = result.getHits(Object.class);  
        System.out.println("[多条精确匹配]查询Size:" + hits.size());

        for (Hit<Object, Void> hit : hits)
        {
        	Object news = hit.source;  
            System.out.println("[多条精确匹配]查询结果:" +news.toString());
        }  
    }  
     
    
    /**
     * 通配符和正则表达式查询  
     * @throws Exception
     */
    @Test  
    public void wildcardQuery() throws Exception
    {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("title.keyword", "*:*");
        searchSourceBuilder.query(queryBuilder);  
        searchSourceBuilder.size(10);  
        searchSourceBuilder.from(0);  
        String query = searchSourceBuilder.toString();

        System.out.println("[正则匹配]查询条件："+query);
        
        Search search = new Search.Builder(query)
                .addIndex(indexName)  
                .addType(typeName)  
                .build();  
        SearchResult result = jestClient.execute(search); 
        
        List<Hit<Object, Void>> hits = result.getHits(Object.class);  
        System.out.println("[正则匹配]查询Size:" + hits.size());

        for (Hit<Object, Void> hit : hits)
        {
          Object news = hit.source;  
          System.out.println("[正则匹配]查询结果:" +news.toString());
        }  
    }  
     
    
    /**
     * 前缀查询
     * prefixQuery：类似于数据库SQL里的like 'Java%'
     * @throws Exception
     */
    @Test  
    public void prefixQuery() throws Exception
    {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        QueryBuilder queryBuilder = QueryBuilders.prefixQuery("title.keyword", "多人");
        searchSourceBuilder.query(queryBuilder);  
        searchSourceBuilder.size(10);  
        searchSourceBuilder.from(0);  
        String query = searchSourceBuilder.toString();      
        System.out.println("[前缀匹配]查询条件："+query);
        
        Search search = new Search.Builder(query)  
                .addIndex(indexName)
                .addType(typeName)  
                .build();  
        SearchResult result = jestClient.execute(search); 
        
        List<Hit<Object, Void>> hits = result.getHits(Object.class);  
        System.out.println("[前缀匹配]查询Size:" + hits.size());

        for (Hit<Object, Void> hit : hits)
        {
          Object news = hit.source;  
          System.out.println("[前缀匹配]查询结果:" +news.toString());
        }  
    }  
    
    
    /**
     * 区间查询  
     * @throws Exception
     */
    @Test  
    public void rangeQuery() throws Exception
    {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        QueryBuilder queryBuilder = QueryBuilders.rangeQuery("date")
            .gte("2018-05-11T00:00:00")
            .lte("2018-05-11T13:10:00")
            .includeLower(true)  
            .includeUpper(true);

        searchSourceBuilder.query(queryBuilder);  
        searchSourceBuilder.size(10);  
        searchSourceBuilder.from(0);  
        String query = searchSourceBuilder.toString();  
        System.out.println("[区间查询]查询条件:" +query);
        
        Search search = new Search.Builder(query)  
                .addIndex(indexName)  
                .addType(typeName)  
                .build();  
        SearchResult result = jestClient.execute(search); 
        
        List<Hit<Object, Void>> hits = result.getHits(Object.class);  
        System.out.println("[区间查询]查询Size:" + hits.size());

        for (Hit<Object, Void> hit : hits)
        {
          Object news = hit.source;  
          System.out.println("[区间查询]查询结果:" +news.toString());
        }  
    }  
    
    
    /**
     * 文本检索
     * 应该是将查询的词先分成词库中存在的词，然后分别去检索，存在任一存在的词即返回，查询词分词后是OR的关系。需要转义特殊字符
     * @throws Exception
     */
    @Test  
    public void queryString() throws Exception
    {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery(QueryParser.escape("国防部"));

        searchSourceBuilder.query(queryBuilder);
        searchSourceBuilder.size(10);  
        searchSourceBuilder.from(0);

        String query = searchSourceBuilder.toString();
        System.out.println("[文本检索]查询条件:" +query);

        Search search = new Search.Builder(query)
                .addIndex(indexName)
                .addType(typeName)
                .build();
        SearchResult result = jestClient.execute(search);

        List<Hit<Object, Void>> hits = result.getHits(Object.class);
        System.out.println("[文本检索]查询Size:" + hits.size());

        for (Hit<Object, Void> hit : hits)
        {
            Object news = hit.source;
            System.out.println("[文本检索]查询结果:" +news.toString());
        }
    }  
    
    /**
     * Count文档 
     * @throws Exception
     */
    @Test  
    public void count() throws Exception
    {
        String[] name = new String[]{ "李四", "麻子" };
        String from = "2018-05-11T00:00:00";
        String to = "2018-05-11T13:20:00";

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();  
        QueryBuilder queryBuilder = QueryBuilders.boolQuery()  
            .must(QueryBuilders.termsQuery("author.keyword", name))
            .must(QueryBuilders.rangeQuery("date").gte(from).lte(to));

        searchSourceBuilder.query(queryBuilder);  
        String query = searchSourceBuilder.toString();
        System.out.println("[文本检索]查询条件:" +query);
       
        Count count = new Count.Builder()  
                .addIndex(indexName)  
                .addType(typeName)  
                .query(query)  
                .build();  
        CountResult results = jestClient.execute(count);   
        
        Double counts = results.getCount();
        System.out.println("[文本检索]查询Count:" + counts);
        System.out.println("[文本检索]查询结果:" + results.getJsonString());
    }  

    /**
     * 根据ID 获取文档
     * Get
     * @throws Exception
     */
    @Test  
    public void get() throws Exception
    {
        String id = "PyOaTWMBmeNLbU8AfYNE";
        
        Get get = new Get.Builder(indexName, id).type(typeName).build();          
        JestResult result = jestClient.execute(get);

        System.out.println("[根据ID获取]查询结果:" +result.getJsonString());

        if (result.isSucceeded())
        {
          Object news = result.getSourceAsObject(Object.class);
          System.out.println("[根据ID获取]查询解析:" + news.toString());
        }
    }  
    
    /**
     * 根据ID删除文档
     * @throws Exception
     */
    @Test  
    public void deleteIndexDocument() throws Exception
    {
        String id = "QiOqTWMBmeNLbU8A4YMq";
        DocumentResult dr = jestClient.execute(new Delete.Builder(id).index(indexName).type(typeName).build());
        System.out.println("[根据ID删除]查询结果:" +dr.getJsonString());

        boolean result = dr.isSucceeded(); 
        System.out.println("[根据ID删除]删除结果:" +result);
    }
    
    /**
     * 删除索引
     * @throws Exception
     */
    @Test  
    public void deleteIndex() throws Exception
    {
    	JestResult jr = jestClient.execute(new DeleteIndex.Builder(indexName).build());
        System.out.println("[删除索引]返回结果:" +jr.getJsonString());
        boolean result = jr.isSucceeded();  
        System.out.println("[删除索引]删除结果:" +result);
    }
    
	/**
	 * 将删除所有的索引
	 * @throws Exception
	 */
    @Test
    public void deleteIndexAll() throws Exception
    {
		DeleteIndex deleteIndex = new DeleteIndex.Builder(typeName).build();
		JestResult result = jestClient.execute(deleteIndex);
        System.out.println("[删除索引]返回结果:" +result.getJsonString());
	}
    
    
	/**
	 * 清缓存
	 * @throws Exception
	 */
    @Test
    public  void clearCache() throws Exception
    {
		ClearCache closeIndex = new ClearCache.Builder().build();
		JestResult result = jestClient.execute(closeIndex);
        System.out.println("[清缓存]返回结果:" +result.getJsonString());
	}
    
	/**
	 * 关闭索引
	 * @throws Exception
	 */
    @Test
    public void closeIndex() throws Exception
    {
		CloseIndex closeIndex = new CloseIndex.Builder(typeName).build();
		JestResult result = jestClient.execute(closeIndex);
		System.out.println("[关闭索引]返回结果:" + result.getJsonString());
	}

	/**
	 * 优化索引
	 * @throws Exception
	 */
    @Test
    public void optimize() throws Exception
    {
		Optimize optimize = new Optimize.Builder().build(); 
		JestResult result = jestClient.execute(optimize);
        System.out.println("[优化索引]返回结果:" + result.getJsonString());
	}

	/**
	 * 刷新索引
	 * @throws Exception
	 */
    @Test
    public void flush() throws Exception
    {
		Flush flush = new Flush.Builder().build(); 
		JestResult result = jestClient.execute(flush);
        System.out.println("[刷新索引]返回结果:" + result.getJsonString());
	}

	/**
	 * 判断索引目录是否存在
	 * @throws Exception
	 */
    @Test
    public void indicesExists() throws Exception
    {
		IndicesExists indicesExists = new IndicesExists.Builder(typeName).build();
		JestResult result = jestClient.execute(indicesExists);
        System.out.println("[判断索引]返回结果:" + result.getJsonString());
	}

	/**
	 * 查看节点信息
	 * @throws Exception
	 */
    @Test
    public void nodesInfo() throws Exception
    {
		NodesInfo nodesInfo = new NodesInfo.Builder().build();
		JestResult result = jestClient.execute(nodesInfo);
        System.out.println("[查看节点信息]返回结果:" + result.getJsonString());
	}

	/**
	 * 查看集群健康信息
	 * @throws Exception
	 */
    @Test
    public void health() throws Exception
    {
		Health health = new Health.Builder().build();
		JestResult result = jestClient.execute(health);
        System.out.println("[查看集群健康信息]返回结果:" + result.getJsonString());
	}

	/**
	 *
	 * @throws Exception
	 */
    @Test
	public void nodesStats() throws Exception
    {
		NodesStats nodesStats = new NodesStats.Builder().build();
		JestResult result = jestClient.execute(nodesStats);
		System.out.println("[节点状态]返回结果:" + result.getJsonString());
	}
    

    /**
	 * 更新Document
	 * @throws Exception
	 */
    @Test
	public void updateDocument() throws Exception
    {
		MyArticle article = new MyArticle();

		article.setTitle("中国3颗卫星拍到阅兵现场高清照");
		article.setContent("据中国资源卫星应用中心报道，9月3日，纪念中国人民抗日战争暨世界反法西斯战争胜利70周年大阅兵在天安门广场举行。资源卫星中心针对此次盛事，综合调度在轨卫星，9月1日至3日连续三天持续观测首都北京天安门附近区域，共计安排5次高分辨率卫星成像。在阅兵当日，高分二号卫星、资源三号卫星及实践九号卫星实现三星联合、密集观测，捕捉到了阅兵现场精彩瞬间。为了保证卫星准确拍摄天安门及周边区域，提高数据处理效率，及时制作合格的光学产品，资源卫星中心运行服务人员从卫星观测计划制定、复核、优化到系统运行保障、光学产品图像制作，提前进行了周密部署，并拟定了应急预案，为圆满完成既定任务奠定了基础。");
		article.setDate(new Date().toString());
		article.setAuthor("张三");

		String script = "{" +
				"    \"doc\" : {" +
				"        \"title\" : \""+article.getTitle()+"\"," +
				"        \"content\" : \""+article.getContent()+"\"," +
				"        \"author\" : \""+article.getAuthor()+"\"," +
				"        \"date\" : \""+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(article.getDate())+"\"" +
				"    }" +
				"}";
		Update update = new Update.Builder(script).index(indexName).type(typeName).id("").build();
		JestResult result = jestClient.execute(update);
		System.out.println("[更新]返回结果："+ result.getJsonString());
	}


    /**
	 * 删除Document
	 * @throws Exception
	 */
    @Test
	public  void deleteDocument() throws Exception
    {
		Delete delete = new Delete.Builder("").index(indexName).type(typeName).build();
		JestResult result = jestClient.execute(delete);
		System.out.println(result.getJsonString());
	}

	/**
	 * 获取Document
	 * @throws Exception
	 */
    @Test
	public void getDocument() throws Exception
    {
		Get get = new Get.Builder(indexName,"").type(typeName).build();
		JestResult result = jestClient.execute(get);
		MyArticle article = result.getSourceAsObject(MyArticle.class);
		System.out.println(article.getTitle()+","+article.getContent());
	}


    /**
	 * 查询全部
	 * @throws Exception
	 */
    @Test
	public void searchAll() throws Exception
    {
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(QueryBuilders.matchAllQuery());

        System.out.println("[查询全部]查询条件："+searchSourceBuilder.toString());

        Search search = new Search.Builder(searchSourceBuilder.toString())
				.addIndex(indexName)
                .addType(typeName)
				.build();
        SearchResult result = jestClient.execute(search);

        System.out.println("[查询全部]查询结果："+result.getJsonString());

		List<Hit<MyArticle,Void>> hits = result.getHits(MyArticle.class);
		for (Hit<MyArticle, Void> hit : hits)
		{
			MyArticle source = hit.source;
            System.out.println("-----------------------------");
			System.out.println("标题："+source.getTitle());
			System.out.println("内容："+source.getContent());
			System.out.println("作者："+source.getAuthor());
            System.out.println("发布时间："+source.getDate());
		}
	}

    /**
     * 搜索高亮显示
     * @throws Exception
     */
    @Test
    public void createSearch() throws Exception
    {
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(QueryBuilders.termQuery("content", "空袭"));
		HighlightBuilder highlightBuilder = new HighlightBuilder();
        //高亮title
		highlightBuilder.field("content");
        //高亮标签
		highlightBuilder.preTags("<em>").postTags("</em>");
        //高亮内容长度
		highlightBuilder.fragmentSize(500);
		searchSourceBuilder.highlighter(highlightBuilder);

		System.out.println("[高亮查询]查询条件："+searchSourceBuilder.toString());

		Search search = new Search.Builder(searchSourceBuilder.toString()).addIndex(indexName) .build();

		SearchResult result = jestClient.execute(search);

		System.out.println("[高亮查询]查询结果："+result.getJsonString());
		System.out.println("[高亮查询]查询数量："+result.getTotal());

		List<Hit<MyArticle,Void>> hits = result.getHits(MyArticle.class);
		for (Hit<MyArticle, Void> hit : hits)
		{
			MyArticle source = hit.source;
			//获取高亮后的内容
			Map<String, List<String>> highlight = hit.highlight;

            //高亮后的title
			List<String> views = highlight.get("content");
			if(views!=null)
			{
				source.setContent(views.get(0));
			}
			System.out.println("标题："+source.getTitle());
			System.out.println("内容："+source.getContent());
            System.out.println("作者："+source.getAuthor());
			System.out.println("时间："+source.getDate());
		}
	}


    /**
     * 分页
     * @throws IOException
     */
    @Test
    public void page() throws IOException
    {
    	int pageNumber=1;
    	int pageSize=2;

    	SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    	searchSourceBuilder.query(QueryBuilders.queryStringQuery("国"));
        //设置起始页
    	searchSourceBuilder.from((pageNumber - 1) * pageSize);
        //设置页大小
        searchSourceBuilder.size(pageSize);
        Search search = new Search.Builder(searchSourceBuilder.toString())
                .addIndex(indexName)
                .build();
        SearchResult result = jestClient.execute(search);

        System.out.println("[分页查询]查询结果："+result.getJsonString());

        List<Hit<MyArticle,Void>> hits = result.getHits(MyArticle.class);
        for (Hit<MyArticle, Void> hit : hits)
        {
            MyArticle source = hit.source;
            System.out.println("-----------------------------");
            System.out.println("标题："+source.getTitle());
            System.out.println("内容："+source.getContent());
            System.out.println("作者："+source.getAuthor());
            System.out.println("发布时间："+source.getDate());
        }

        // 自动解析
        JsonObject jsonObject = result.getJsonObject();
        JsonObject hitsobject = jsonObject.getAsJsonObject("hits");

        long took = jsonObject.get("took").getAsLong();
        long total = hitsobject.get("total").getAsLong();

        System.out.println("took:"+took+"  "+"total:"+total);
    }
    
}
